import logging
from datetime import datetime

from django.core.management import BaseCommand

from conf import models
from lib import utils, sina, dingding

log = logging.getLogger("log")

# 用户数据
user_backup_stocks: dict[str, models.BackupStock] = {}
user_dings: list[models.Dingding] = []


def load_user_data(user_id: int = None):
    """从数据库加载用户数据"""

    global user_dings

    stocks = list(models.BackupStock.objects.filter(user_id=user_id))
    user_dings = list(models.Dingding.objects.filter(user_id=user_id, enable=True))

    for i in stocks:
        user_backup_stocks.update({
            i.code: i
        })


class Command(BaseCommand):
    help = "扫描备选股票"

    def add_arguments(self, parser):
        parser.add_argument(
            "user_id", nargs="?", help="指定用户"
        )

    def handle(self, *args, **options):

        user_id = options.get("user_id")
        load_user_data(user_id)

        batch_10 = utils.chunk_list(list(user_backup_stocks.values()), 10)

        backup_to_ready_stocks = []
        for stocks in batch_10:
            stock_measures = sina.get_stock_data([i.code for i in stocks])
            for measure in stock_measures:
                backup_stock = user_backup_stocks.get(measure.code)

                backup_stock.name = measure.name
                backup_stock.current_price = measure.real_price
                backup_stock.collect_datetime = datetime.now()
                backup_stock.save()

                # 选中落入价格预期范围的股票
                if backup_stock.min <= measure.real_price <= backup_stock.max:
                    ready_stock = dingding.BackupToReadyStock(measure.code, measure.name, measure.real_price,
                                                              backup_stock.advice, backup_stock.message)
                    backup_to_ready_stocks.append(ready_stock)

        # 汇总转正的消息后，统一发送消息
        send_dings = set()
        not_send_dings = set()
        body = dingding.backup_to_ready_stocks_body(backup_to_ready_stocks)
        for ding in user_dings:
            print(ding.name)
            try:
                dingding.send(body, ding.access_token, ding.secret)
                send_dings.add(ding.name)
            except Exception as e:
                not_send_dings.add(ding.name)
                log.error(f"[{ding.name}] 钉钉发消息异常：{e}", exc_info=True)
                continue

        msg = f"入选数量：{len(backup_to_ready_stocks)}"
        if send_dings:
            msg += f"，已发送群：{','.join(send_dings)}"
        if not_send_dings:
            msg += f"，发送失败群：{','.join(not_send_dings)}"
        return msg
